export default {
  init: function (tg, option) {
    let svg = window.d3.select(tg);
    let WIDTH = 20;
    let HEIGHT = 80;
    let ALARM_POINT = WIDTH / 3.2;
    let color = '#2d8ee5';
    let alarmColor = '#00e55d';
    let title = option.title;
    let wholeWrap = svg.append('g');
    let wrap = wholeWrap.append('g');
    let bottomWrap = wrap.append('ellipse');
    let rect = wrap.append('rect');
    let innerBottom = wrap.append('ellipse');
    let innerRect = wrap.append('rect');
    let innerShadow = wrap.append('rect');
    let innerTop = wrap.append('ellipse');
    let highlight = wrap.append('rect');
    let top = wrap.append('ellipse');
    let defs = svg.append('defs');
    let alarmWrap = wrap.append('circle');
    let alarm = wrap.append('circle');
    let alarmShadow = wrap.append('circle');
    let alarmHighlight = wrap.append('circle');
    let text = wholeWrap.append('text');
    let hitArea = wholeWrap.append('rect');
    let events = {};
    let creatGradient = function (id, config) {
      let color1 = config.color1 || '#000';
      let color2 = config.color2 || '#fff';
      let type = config.type || 'linearGradient';
      let x1 = config.x1 || '0%';
      let y1 = config.y1 || '0%';
      let x2 = config.x2 || '100%';
      let y2 = config.y2 || '0%';
      let r = config.r;
      let fx = config.fx;
      let fy = config.fy;
      let offset1 = config.offset1 || '0%';
      let offset2 = config.offset2 || '100%';
      let linearGradient = defs.append(type)
        .attr('id', id)
        .attr('x1', x1)
        .attr('y1', y1)
        .attr('x2', x2)
        .attr('y2', y2)
        .attr('r', r)
        .attr('fx', fx)
        .attr('fy', fy);
      linearGradient.append('stop')
        .attr('offset', offset1)
        .style('stop-color', color1);
      linearGradient.append('stop')
        .attr('offset', offset2)
        .style('stop-color', color2);
    };
    let setAttr = function (config) {
      let cur = this;
      for (let i in config) {
        cur.attr(i, config[i]);
      }
    };
    let setStyle = function (config) {
      let cur = this;
      for (let i in config) {
        cur.style(i, config[i]);
      }
    };

    function ThreeDbar () {
      wrap.attr('transform', 'scale(1,-1)');
      text.text(title);
      setAttr.call(text, {
        transform: 'translate(-12, ' + (HEIGHT / 5) + ')'
      });
      setStyle.call(text, {
        fill: '#f1d516',
        'font-size': '12px',
        'font-weight': 'bold'
      });
      creatGradient('innerShadow', {
        color1: 'rgba(0,0,0,.2)',
        color2: 'rgba(0,0,0,0)',
        x1: '0%',
        x2: '0%',
        y1: '100%'
      });
      creatGradient('wrapShadow', {
        color1: '#999',
        color2: '#ccc',
        x1: '0%',
        x2: '0%',
        y1: '100%'
      });
      creatGradient('alarmShadow', {
        type: 'radialGradient',
        color1: 'rgba(0,0,0,0)',
        color2: 'rgba(0,0,0,.3)',
        x1: '0%',
        x2: '0%',
        r: '50%',
        fx: '50%',
        fy: '50%'
      });
      creatGradient('highlight', {
        color1: 'rgba(250,250,250,1)',
        color2: 'rgba(250,250,250,0)',
        x1: '0%',
        x2: '0%',
        y1: '100%'
      });
      creatGradient('alarmHighlight', {
        color1: 'rgba(250,250,250,1)',
        color2: 'rgba(250,250,250,0)',
        x1: '0%',
        y1: '100%',
        x2: '0%',
        y2: '0%',
        offset2: '50%'
      });
      setAttr.call(alarmWrap, {
        cx: WIDTH / 2,
        cy: ALARM_POINT * 0.3,
        r: ALARM_POINT * 1.2
      });
      setStyle.call(alarmWrap, {
        fill: 'url(#wrapShadow)'
      });
      setAttr.call(alarm, {
        cx: WIDTH / 2,
        cy: ALARM_POINT * 0.3,
        r: ALARM_POINT
      });
      setStyle.call(alarm, {
        fill: alarmColor
      });
      setAttr.call(alarmShadow, {
        cx: WIDTH / 2,
        cy: ALARM_POINT * 0.3,
        r: ALARM_POINT
      });
      setAttr.call(hitArea, {
        width: WIDTH,
        height: HEIGHT,
        transform: 'translate(0,-' + HEIGHT + ')'
      });
      setStyle.call(hitArea, {
        fill: 'blue',
        opacity: 0,
        cursor: 'pointer'
      });
      setStyle.call(alarmShadow, {
        fill: 'url(#alarmShadow)'
      });
      setAttr.call(alarmHighlight, {
        cx: WIDTH / 2,
        cy: ALARM_POINT * 0.3,
        r: ALARM_POINT * 0.8
      });
      setStyle.call(alarmHighlight, {
        fill: 'url(#alarmHighlight)'
      });
      setAttr.call(rect, {
        width: WIDTH,
        height: HEIGHT
      });
      setStyle.call(rect, {
        fill: '#fff',
        opacity: 0.3
      });
      setAttr.call(highlight, {
        transform: 'translate(' + WIDTH / 10 + ',' + HEIGHT * 0.3 + ')',
        width: WIDTH / 5,
        height: HEIGHT * 0.7
      });
      setStyle.call(highlight, {
        fill: 'url(#highlight)'
      });
      setAttr.call(innerRect, {
        width: WIDTH,
        height: 0
      });
      setAttr.call(innerShadow, {
        width: WIDTH,
        height: 0
      });
      innerRect.style('fill', color);
      innerShadow.style('fill', 'url(#innerShadow)');
      setAttr.call(top, {
        cx: WIDTH / 2,
        cy: HEIGHT,
        rx: WIDTH / 2,
        ry: WIDTH / 6
      });
      setStyle.call(top, {
        fill: 'url(#wrapShadow)',
        opacity: 1
      });
      setAttr.call(innerTop, {
        cx: WIDTH / 2,
        cy: 0,
        rx: WIDTH / 2,
        ry: WIDTH / 6
      });
      innerTop.style('fill', color);
      setAttr.call(innerBottom, {
        cx: WIDTH / 2,
        cy: 0,
        rx: WIDTH / 2,
        ry: WIDTH / 6
      });
      innerBottom.style('fill', color);
      setAttr.call(bottomWrap, {
        cx: WIDTH / 2,
        cy: 0,
        rx: WIDTH / 2 * 1.4,
        ry: WIDTH / 6 * 1.4
      });
      bottomWrap.style('fill', 'url(#wrapShadow)');
      hitArea.on('click', function (event) {
        if (events['click']) {
          events['click'](event);
        }
      });
    };
    ThreeDbar.prototype.setColor = function (clr) {
      color = clr;
      innerRect.style('fill', color);
      innerTop.style('fill', color);
      innerBottom.style('fill', color);
      return this;
    };
    ThreeDbar.prototype.setPos = function (pos) {
      wholeWrap.attr('transform', 'translate(' + pos.x + ',' + pos.y + ')');
      return this;
    };
    ThreeDbar.prototype.setValue = function (value) {
      let DURATION = 1000;
      let height = HEIGHT * value / 100;
      innerTop.transition().duration(DURATION).attr('cy', height);
      innerRect.transition().duration(DURATION).attr('height', height);
      innerShadow.transition().duration(DURATION).attr('height', height);
      return this;
    };
    ThreeDbar.prototype.on = function (eventName, handler) {
      events[eventName] = handler;
      return this;
    };
    ThreeDbar.prototype.setAlarmStatus = function (status) {
      let color = '';
      switch (status) {
        case 4:
          color = '#e74e53';
          break;
        case 3:
          color = '#ee6b1c';
          break;
        case 2:
          color = '#ece417';
          break;
        case 1:
          color = '#00bc79';
          break;
        default:
          color = '#00bc79';
          break;
      }
      setStyle.call(alarm, {
        fill: color
      });
      return this;
    };
    return new ThreeDbar(tg);
  }
};
